# -*- coding: utf-8 -*-

"""
@author: 猿小天
@contact: QQ:1638245306
@Created on: 2021/6/1 001 22:38
@Remark: 菜单模块
"""
from rest_framework import serializers
from rest_framework.decorators import action

from dvadmin.system.models import Menu, RoleMenuPermission
from dvadmin.system.views.menu_button import MenuButtonSerializer
from dvadmin.utils.json_response import SuccessResponse, ErrorResponse
from dvadmin.utils.serializers import CustomModelSerializer
from dvadmin.utils.viewset import CustomModelViewSet


class MenuSerializer(CustomModelSerializer):
    """
    菜单表的简单序列化器
    """
    # menuPermission = serializers.SerializerMethodField(read_only=True)
    # hasChild = serializers.SerializerMethodField()
    parentId = serializers.SerializerMethodField()
    children = serializers.SerializerMethodField()

    # def get_menuPermission(self, instance):
    #     queryset = instance.menuPermission.order_by('-name').values('id', 'name', 'value')
    #     # MenuButtonSerializer(instance.menuPermission.all(), many=True)
    #     if queryset:
    #         return queryset
    #     else:
    #         return None

    # def get_hasChild(self, instance):
    #     hasChild = Menu.objects.filter(parent=instance.id)
    #     if hasChild:
    #         return True
    #     return False

    def get_children(self, instance):

        return []

    def get_parentId(self, instance):
        return instance.parent_id if instance.parent_id else 0

    class Meta:
        model = Menu
        fields = "__all__"
        read_only_fields = ["id"]


class MenuCreateSerializer(CustomModelSerializer):
    """
    菜单表的创建序列化器
    """
    name = serializers.CharField(required=False)

    def create(self, validated_data):
        menu_obj = Menu.objects.filter(parent_id=validated_data.get('parent', None)).order_by('-sort').first()
        last_sort = menu_obj.sort if menu_obj else 0
        validated_data['sort'] = last_sort + 1
        return super().create(validated_data)

    class Meta:
        model = Menu
        fields = "__all__"
        read_only_fields = ["id"]


class WebRouterSerializer(CustomModelSerializer):
    """
    前端菜单路由的简单序列化器
    """
    path = serializers.CharField(source="web_path")
    title = serializers.CharField(source="name")

    class Meta:
        model = Menu
        fields = (
            'id', 'parent', 'icon', 'sort', 'path', 'name', 'title', 'is_link','link_url', 'is_catalog', 'web_path', 'component',
            'component_name', 'cache', 'visible','is_iframe','is_affix', 'status')
        read_only_fields = ["id"]

class UserConstants:
    LAYOUT = "Layout"
    INNER_LINK = "InnerLink"
    PARENT_VIEW = "ParentView"
    TYPE_DIR = "D"
    TYPE_MENU = "M"
    NO_FRAME = "1"
class MenuViewSet(CustomModelViewSet):
    """
    菜单管理接口
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """
    queryset = Menu.objects.all()
    serializer_class = MenuSerializer
    create_serializer_class = MenuCreateSerializer
    update_serializer_class = MenuCreateSerializer
    search_fields = ['name', 'status']
    filter_fields = ['parent', 'name', 'status', 'is_link', 'visible', 'cache', 'is_catalog']

    def list(self, request):
        """懒加载"""
        request.query_params._mutable = True
        params = request.query_params
        parent = params.get('parent', None)
        page = params.get('page', None)
        limit = params.get('limit', None)
        if page:
            del params['page']
        if limit:
            del params['limit']
        if params:
            if parent:
                queryset = self.queryset.filter(parent=parent)
            else:
                queryset = self.queryset.filter()
        else:
            queryset = self.queryset.filter()
        queryset = self.filter_queryset(queryset)
        serializer = MenuSerializer(queryset, many=True, request=request)
        data = serializer.data
        return SuccessResponse(data=data)

    @action(methods=['GET'], detail=False, permission_classes=[])
    def web_router(self, request):
        """用于前端获取当前角色的路由"""
        user = request.user

        # 根据用户角色获取菜单
        if user.is_superuser:
            queryset = Menu.objects.filter(status=1).order_by('parent_id', 'order_num')
        else:
            role_list = user.role.values_list('id', flat=True)
            menu_ids = RoleMenuPermission.objects.filter(role__in=role_list).values_list('menu_id', flat=True)
            queryset = Menu.objects.filter(id__in=menu_ids).order_by('parent_id', 'order_num')

        # 获取菜单树结构
        menus = self.get_child_perms(queryset, 0)

        # 构建符合格式的菜单数据
        router_menus = self.build_menus(menus)


        return SuccessResponse(data=router_menus, msg="获取成功")

    def get_child_perms(self, menus, parent_id):
        menu_dict = {menu.id: menu for menu in menus}  # 创建菜单字典
        return_list = []

        def capitalize_first_letter(input_string):
            if not input_string:  # 检查字符串是否为空
                return input_string
            return input_string[0].upper() + input_string[1:]

        def build_menu_tree(menu, is_top_level=True):
            # 从菜单对象创建格式符合要求的字典
            menu_data = {
                "name": capitalize_first_letter(menu.path) if menu.path else capitalize_first_letter(menu.menu_name),
                "path": '/' + menu.path if is_top_level and menu.path else menu.path if menu.path else None,
                "hidden": menu.visible == "1",
                "component": menu.component if menu.component else "Layout",
                "alwaysShow": menu.menu_type == 'M',
                "meta": {
                    "title": menu.menu_name,
                    "icon": menu.icon,
                    "noCache": menu.is_cache == "0",
                    "link": menu.link_url if getattr(menu, 'is_link', None) == '1' else None
                },
            }
            
            has_children = any(child.parent_id == menu.id for child in menus)
            if has_children:
                children = [build_menu_tree(menu_dict[child.id], False) for child in menus if child.parent_id == menu.id and child.menu_type != 'F']
                if children:
                    menu_data['children'] = children  # 添加子菜单
                if menu.menu_type != 'F':
                    menu_data["redirect"] = "noRedirect"
                if menu.path == 'log':
                    menu_data['component'] = 'ParentView'
            
            if not is_top_level and menu.menu_type != 'M':
                menu_data.pop('alwaysShow', None)
            
            return menu_data

        for menu in menus:
            if menu.parent_id == parent_id:
                return_list.append(build_menu_tree(menu))  # 添加根菜单

        return return_list

    def build_menus(self, menus):
        """构建符合格式的路由菜单"""
        routers = []

        for menu in menus:
            # 确保接收到的是字典格式的菜单
            if isinstance(menu, dict):
                menu_dict = {
                    "name": menu['name'],
                    "path": menu['path'],
                    "hidden": menu['hidden'],
                    "component": menu['component'],
                    "alwaysShow": menu.get('alwaysShow'),
                    "meta": {
                        "title": menu['meta']['title'],
                        "icon": menu['meta']['icon'],
                        "noCache": menu['meta']['noCache'],
                         "link": menu['meta']['link'] if menu['meta']['link'] else None
                    },
                }
                if menu.get('children'):
                    menu_dict['children'] = menu.get('children')
                if menu.get('redirect'):
                    menu_dict['redirect'] = menu.get('redirect')
                
                if not menu.get('children'):
                    menu_dict.pop('children', None)
                if not menu.get('redirect'):
                    menu_dict.pop('redirect', None)
                
                routers.append(menu_dict)

        return routers

    @action(methods=['GET'], detail=False, permission_classes=[])
    def  roleMenuTreeselect(self, request):
        """获取角色菜单树选择"""
        user = request.user
        if not user.is_superuser:
            role_list = user.role.values_list('id', flat=True)
            menu_list = RoleMenuPermission.objects.filter(role__in=role_list).values_list('menu_id')
            queryset = Menu.objects.filter(id__in=menu_list)
            print(queryset)



    @action(methods=['GET'], detail=False, permission_classes=[])
    def get_all_menu(self, request):
        """用于菜单管理获取所有的菜单"""
        user = request.user
        queryset = self.queryset.all()
        if not user.is_superuser:
            role_list = user.role.values_list('id', flat=True)
            menu_list = RoleMenuPermission.objects.filter(role__in=role_list).values_list('menu_id')
            queryset = Menu.objects.filter(id__in=menu_list)
        serializer = WebRouterSerializer(queryset, many=True, request=request)
        data = serializer.data
        return SuccessResponse(data=data, total=len(data), msg="获取成功")

    @action(methods=['POST'], detail=False, permission_classes=[])
    def move_up(self, request):
        """菜单上移"""
        menu_id = request.data.get('menu_id')
        try:
            menu = Menu.objects.get(id=menu_id)
        except Menu.DoesNotExist:
            return ErrorResponse(msg="菜单不存在")
        previous_menu = Menu.objects.filter(sort__lt=menu.sort, parent=menu.parent).order_by('-sort').first()
        if previous_menu:
            previous_menu.sort, menu.sort = menu.sort, previous_menu.sort
            previous_menu.save()
            menu.save()
        return SuccessResponse(data=[], msg="上移成功")

    @action(methods=['POST'], detail=False, permission_classes=[])
    def move_down(self, request):
        """菜单下移"""
        menu_id = request.data['menu_id']
        try:
            menu = Menu.objects.get(id=menu_id)
        except Menu.DoesNotExist:
            return ErrorResponse(msg="菜单不存在")
        next_menu = Menu.objects.filter(sort__gt=menu.sort, parent=menu.parent).order_by('sort').first()
        if next_menu:
            next_menu.sort, menu.sort = menu.sort, next_menu.sort
            next_menu.save()
            menu.save()
        return SuccessResponse(data=[], msg="下移成功")
